using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using Microsoft.Practices.CompositeUI;
using NUnit.Framework;
using SCSFContrib.CompositeUI.WPF.Activation;
using SCSFContrib.CompositeUI.WPF.UnitTest;

namespace SCSFContrib.CompositeUI.WPF.FunctionalTest.Activation
{
	[TestFixture]
	public sealed class FrameworkElementActivationServiceTest : FunctionalTest
	{
		private TestableRootWorkItem _workItem;
		private FrameworkElementActivationService _frameworkElementActivationService;

		protected override void SetUpCore()
		{
			base.SetUpCore();
			_workItem = new TestableRootWorkItem();
			_frameworkElementActivationService = new FrameworkElementActivationService(_workItem);
		}

		[Test]
		public void FrameworkElementAdded_ShouldActivateWorkItemWhenFrameworkElementReceivesFocus()
		{
			TextBox textBox = new TextBox();
			Window window = CreateWindow(textBox);

			_frameworkElementActivationService.FrameworkElementAdded(textBox);

			window.Show();
			Assert.AreEqual(WorkItemStatus.Inactive, _workItem.Status);
			Keyboard.Focus(textBox);
			Assert.AreEqual(WorkItemStatus.Active, _workItem.Status);
		}

		[Test]
		public void FrameworkElementAdded_ShouldntActivateWorkItemWhenExemptFrameworkElementReceivesFocus()
		{
			TextBox textBox = new TextBox();
			MenuItem menuItem = new MenuItem();
			StackPanel stackPanel = new StackPanel();
			stackPanel.Children.Add(textBox);
			stackPanel.Children.Add(menuItem);
			Window window = CreateWindow(stackPanel);

			_frameworkElementActivationService.FrameworkElementAdded(textBox);
			_frameworkElementActivationService.FrameworkElementAdded(menuItem);
			FrameworkElementActivationService.SetIsExempt(textBox, true);

			window.Show();
			Assert.AreEqual(WorkItemStatus.Inactive, _workItem.Status);
			Keyboard.Focus(textBox);
			Assert.AreEqual(WorkItemStatus.Inactive, _workItem.Status);
			Keyboard.Focus(menuItem);
			Assert.AreEqual(WorkItemStatus.Inactive, _workItem.Status);
		}

		[Test]
		public void FrameworkElementAdded_ShouldntActivateWorkItemWhenUnloadedFrameworkElementReceivesFocus()
		{
			TextBox textBox = new TextBox();
			Window window = CreateWindow(textBox);

			_frameworkElementActivationService.FrameworkElementAdded(textBox);

			window.Show();
			window.Close();
			Assert.AreEqual(WorkItemStatus.Inactive, _workItem.Status);
			Keyboard.Focus(textBox);
			Assert.AreEqual(WorkItemStatus.Inactive, _workItem.Status);
		}

		[Test]
		public void FrameworkElementRemoved_ShouldntActivateWorkItemWhenFrameworkElementReceivesFocus()
		{
			TextBox textBox1 = new TextBox();
			TextBox textBox2 = new TextBox();
			StackPanel stackPanel = new StackPanel();
			stackPanel.Children.Add(textBox1);
			stackPanel.Children.Add(textBox2);
			Window window = CreateWindow(stackPanel);

			_frameworkElementActivationService.FrameworkElementAdded(textBox1);
			_frameworkElementActivationService.FrameworkElementAdded(textBox2);
			_frameworkElementActivationService.FrameworkElementRemoved(textBox1);

			window.Show();
			Assert.AreEqual(WorkItemStatus.Inactive, _workItem.Status);
			Keyboard.Focus(textBox1);
			Assert.AreEqual(WorkItemStatus.Inactive, _workItem.Status);
			Keyboard.Focus(textBox2);
			Assert.AreEqual(WorkItemStatus.Active, _workItem.Status);
		}
	}
}